import { ImageSourcePropType, StyleSheet, View } from "react-native";
import Animated, { useAnimatedStyle, useSharedValue, withSpring, withClamp } from 'react-native-reanimated';
import { Gesture, GestureDetector } from "react-native-gesture-handler";
type Props = {
    size: number
    source: ImageSourcePropType
}




export default function EmojiSticker({ size, source }: Props) {

    /**
     * useSharedValue 是 Reanimated 库提供的一个核心 Hook，
     * 用于创建可在 UI 线程和 JavaScript 线程之间共享的可变值。
     * 它是实现高性能动画和交互的关键工具。
     * 
     * 1. 为什么需要 useSharedValue？
            React Native 的渲染分为两个线程：
                1. JavaScript 线程：处理 React 组件逻辑、事件处理等。
                2. UI 线程：负责实际渲染和动画执行。

        传统的 React state 更新会触发重渲染，且数据传递需要跨线程通信，可能导致性能瓶颈。
        而 useSharedValue 创建的值可以直接在 UI 线程中访问和修改，无需等待 JavaScript 线程，从而实现流畅的动画效果。
     */
    const scaleImage = useSharedValue(size)
    // 创建一个双击的手势
    const doubleTap = Gesture.Tap() // 创建一个点击手势识别器
        .numberOfTaps(2) // 双击2次
        .onStart(() => { // 双击2次后开始执行回调函数
            if (scaleImage.value != size * 4) { // 双击后执行4倍缩放
                scaleImage.value *= 4;
            } else {
                scaleImage.value = Math.round(scaleImage.value / 4);
            }
        });

    // 创建一个拖动的手势
    const translateX = useSharedValue(0) // 拖动手势x轴初始值
    const translateY = useSharedValue(0) // y轴
    const drag = Gesture.Pan().onChange((e) => {
        translateX.value += e.changeX
        translateY.value += e.changeY
    })
    /**
     * 这一步是创建的可拖动的范围吗?, 这里没有检测边界范围, 这其实是一个自由拖动
     * 导致可以拖到屏幕外边, 后续优化成只在指定范围内拖动
     */
    const containerStyle = useAnimatedStyle(() => {
        return {
            transform: [
                { translateX: translateX.value },
                { translateY: translateY.value }
            ]
        }
    })

    /**
     * useAnimatedStyle 是 Reanimated 提供的 Hook，用于创建可直接在 UI 线程运行的动画样式。
     * 返回的样式对象会被应用到 Animated.View 或 Animated.Image 等组件上。
     */
    const imageStyle = useAnimatedStyle(() => {
        return {
            width: withSpring(scaleImage.value),
            height: withSpring(scaleImage.value, { damping: 10 })
        }
    });

    return (
        <GestureDetector gesture={drag}>
            <Animated.View style={[containerStyle, { top: -350 }]}>
                <GestureDetector gesture={doubleTap}>
                    <Animated.Image source={source} resizeMode="contain" style={[imageStyle, { width: size, height: size }]} />
                </GestureDetector>
            </Animated.View>
        </GestureDetector>
    )
}

const styles = StyleSheet.create({
    sticker: {
        top: -350
    }
})
